home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / mail / mmdf / mmdf-IIb.43 / uip / unsupported / cvmbox.c < prev    next >
Encoding:
C/C++ Source or Header  |  1988-03-28  |  6.0 KB  |  310 lines

  1. /*
  2.  *    SYNOPSIS
  3.  *        cvmbox file ...
  4.  *    DESCRIPTION
  5.  *        This program expects its input (either the argument files
  6.  *        or standard input) to be in the old mailbox format.  It
  7.  *        writes to standard output a mailbox file in the new format.
  8.  *        This program was based on a program called "mailsplit"
  9.  *        written by Dick Grune, Vrije Universiteit, Amsterdam.
  10.  *    AUTHOR    Sjoerd Mullender, Vrije Universiteit, Amsterdam
  11.  *    VERSION    Fri Jan 31 13:05:35 MET 1986
  12.  *    Mods:   Timothy Wood AMC-LSSA: Made Plexus 3.2 changes.
  13.  */
  14.  
  15. #include    <stdio.h>
  16. extern char *sprintf();
  17. extern char *strcat(), *strcpy();
  18.  
  19. char mail_delim[] = "\1\1\1\1\n";
  20.  
  21. char *weekdays[] = {
  22.     "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", 0
  23. };
  24.  
  25. char *months[] = {
  26.     "Jan", "Feb", "Mar", "Apr", "May", "Jun",
  27.     "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", 0
  28. };
  29.  
  30. char *word(), *search_text();
  31.  
  32. char *iname;            /* name of input file */
  33. FILE *ifile;            /* its stream */
  34. int lncnt;            /* its line count */
  35. char date[40];            /* our version of the Date: line */
  36. char from[1024];        /* our version of the From: line */
  37. int date_present;        /* there was a Date: line in the header */
  38. int from_present;        /* there was a From: line in the header */
  39.  
  40. main(argc, argv)
  41. char *argv[];
  42. {
  43.     if (argc == 1) {
  44.         iname = "stdin";
  45.         ifile = stdin;
  46.         lncnt = 0;
  47.         process();
  48.     }
  49.     else
  50.     while (argc > 1) {
  51.         iname = argv[1];
  52.         ifile = fopen(iname, "r");
  53.         if (ifile == NULL)
  54.             error("cannot open %s", iname);
  55.         lncnt = 0;
  56.         process();
  57.         fclose(ifile);
  58.         argc--, argv++;
  59.     }
  60.     
  61.     return 0;
  62. }
  63.  
  64. process()
  65. {
  66.     if (!get_new_line())        /* one-line read-ahead */
  67.         return;
  68.     do {
  69.         date_present = 0;
  70.         from_present = 0;
  71.         fputs(mail_delim, stdout);
  72. /* Plexus 3.2 compiler recognizes only 7 significant characters in names */
  73. #ifdef PLEXUS
  74.         xcopy_header();
  75. #else PLEXUS
  76.         copy_header();
  77. #endif PLEXUS
  78.         copy_letter();
  79.         fputs(mail_delim, stdout);
  80.     } while (is_header_line());
  81. }
  82.  
  83. char line[1024];
  84.  
  85. int
  86. get_new_line()
  87. {
  88.     if (fgets(line, sizeof line, ifile) == NULL)
  89.         return 0;
  90.     lncnt++;
  91.     return 1;
  92. }
  93.  
  94. int
  95. is_header_line()
  96. {
  97.     return strncmp(line, "From ", 5) == 0;
  98. }
  99.  
  100. #ifdef PLEXUS
  101. xcopy_header()
  102. #else PLEXUS
  103. copy_header()
  104. #endif PLEXUS
  105. {
  106.     condense_From_line();
  107.     make_date();
  108.     while (get_new_line() && line[0] != '\n')
  109.         copy_header_line();
  110.     if (from_present)
  111.         printf("Apparently-%s", from);
  112.     else
  113.         fputs(from, stdout);
  114.     if (!date_present)
  115.         fputs(date, stdout);
  116. }
  117.  
  118. copy_header_line()
  119. {
  120.     int ch;
  121.     
  122.     if (strncmp(line, "Date: ", 6) == 0)
  123.         date_present = 1;
  124.     if (strncmp(line, "From: ", 6) == 0)
  125.         from_present = 1;
  126.     fputs(line, stdout);
  127. }
  128.  
  129. copy_letter()
  130. {
  131.     do    fputs(line, stdout);
  132.     while (get_new_line() && !is_header_line());
  133. }
  134.  
  135. condense_From_line()
  136. {
  137.     /* will try to read successive >From lines and compose
  138.      * a summary line.
  139.      */
  140.     char name[1024];
  141.     char prefix[1024];
  142.     int ch;
  143.     
  144.     dissect_line(name, prefix, date);
  145.     while ((ch = getc(ifile)) == '>') {
  146.         if (!get_new_line())
  147.             error("Abrupt EOF", (char *)0);
  148.         dissect_line(name, &prefix[strlen(prefix)], date);
  149.     }
  150.     ungetc(ch, ifile);        /* regrettable */
  151.     sprintf(from, "From: %s%s\n", prefix, name);
  152. }
  153.  
  154. dissect_line(nm, pr, dt)
  155.     char *nm, *pr, *dt;
  156. {
  157.     /* dissects the line into a name, in nm, a prefix (from
  158.      * the 'remote from' part, in pr, and the date in dt,
  159.      * if dt is not NULL.
  160.      */
  161.     char *wd = word(line, NULL);        /* skip From */
  162.     char *rm = search_text(line, "remote from ");
  163.     
  164.     line[strlen(line) - 1] = '\0';        /* remove NL */
  165.     wd = word(wd, nm);            /* the name */
  166.     if (rm) {
  167.         char *rn = word(word(rm, NULL), NULL);
  168.         if (!rn)
  169.             /*bad_format()*/;
  170.         rn = word(rn, pr);        /* the prefix */
  171.         if (rn)
  172.             /*bad_format()*/;
  173.         strcat(pr, "!");
  174.         while (rm[-1] == ' ')
  175.             *--rm = '\0';
  176.     }
  177.     else
  178.         *pr ='\0';            /* no prefix */
  179.     if (dt)
  180.         strcpy(dt, wd);            /* the date */
  181. }
  182.  
  183. make_date()
  184. {
  185.     /* Parses the date part of a From line and makes a Date: line out of
  186.      * it.  This date has the following format:
  187.      * DDD MMM d[d] hh:mm[:ss] yyyy [ZZZ]
  188.      * where DDD is the day of the week, MMM is the month, d[d] is the
  189.      * day of the month, hh:mm:ss is the time, yyyy is the year and ZZZ
  190.      * is the timezone.
  191.      */
  192.     char timezone[10];
  193.     int weekday;
  194.     int year = 0, month = 1, day = 0;
  195.     int hour = 0, min = 0, sec = 0;
  196.     char *wd = date;
  197.     int n;
  198.  
  199.     weekday = wordpos(wd, weekdays);
  200.     if (weekday == 0)
  201.         formaterr(iname, lncnt);
  202.     wd = word(wd, NULL);
  203.     
  204.     month = wordpos(wd, months);
  205.     if (month == 0)
  206.         formaterr(iname, lncnt);
  207.     wd = word(wd, NULL);
  208.     
  209.     if (sscanf(wd, "%d", &day) != 1)
  210.         formaterr(iname, lncnt);
  211.     wd = word(wd, NULL);
  212.     
  213.     if ((n = sscanf(wd, "%d:%d:%d", &hour, &min, &sec)) != 3 && n != 2)
  214.         formaterr(iname, lncnt);
  215.     if (n == 2)
  216.         sec = 0;
  217.     wd = word(wd, NULL);
  218.     
  219.     if ('A' <= *wd && *wd <= 'Z')        /* time zone indicator */
  220.         wd = word(wd, timezone);
  221.     else
  222.         timezone[0] = 0;
  223.     if (sscanf(wd, "%d", &year) != 1)
  224.         formaterr(iname, lncnt);
  225.     wd = word(wd, NULL);
  226.     
  227.     sprintf(date, "Date: %s, %d %s %d %02d:%02d:%02d %s\n",
  228.         weekdays[weekday-1], day, months[month-1],
  229.         year-1900, hour, min, sec, timezone);
  230. }
  231.  
  232. char *
  233. word(s, bf)
  234.     char *s, *bf;
  235. {
  236.     /* returns the address of the first new word after s,
  237.      * or NULL otherwise.
  238.      * If bf is not 0, the word is copied to the buffer bf.
  239.      */
  240.     if (!s) {
  241.         if (bf)
  242.             *bf = '\0';
  243.         return NULL;
  244.     }
  245.     while (*s && *s != ' ' && *s != '\t') {
  246.         if (bf)
  247.             *bf++ = *s;
  248.         s++;
  249.     }
  250.     if (bf)
  251.         *bf = '\0';
  252.     while (*s && (*s == ' ' || *s == '\t'))
  253.         s++;
  254.     if (!*s)
  255.         return NULL;
  256.     return s;
  257. }
  258.  
  259. char *
  260. search_text(ln, txt)
  261.     char *ln, *txt;
  262. {
  263.     /* returns a pointer to the text txt in the array ln,
  264.      * or NULL otherwise.
  265.      */
  266.     int length = strlen(txt);
  267.     
  268.     while (*ln) {
  269.         if (strncmp(ln, txt, length) == 0)
  270.             return ln;
  271.         ln++;
  272.     }
  273.     return NULL;
  274. }
  275.  
  276. int
  277. wordpos(wd, lst)
  278.     char *wd, *lst[];
  279. {
  280.     /* the index (starting at 1) of the word in the list or
  281.      * 0 otherwise
  282.      */
  283.     int pos = 0;
  284.     
  285.     if (!wd)
  286.         return 0;
  287.     while (lst[pos] && strncmp(wd, lst[pos], strlen(lst[pos])) != 0)
  288.         pos++;
  289.     if (!lst[pos])
  290.         return 0;
  291.     return pos+1;
  292. }
  293.  
  294. formaterr(inm, lc)
  295.     char *inm;
  296. {
  297.     char buff[300];
  298.     
  299.     sprintf(buff, "\"%s\", line %d: improper date format", inm, lc);
  300.     error("%s", buff);
  301. }
  302.  
  303. error(fmt, str)
  304.     char *fmt, *str;
  305. {
  306.     fprintf(stderr, fmt, str);
  307.     fprintf(stderr, "\n");
  308.     exit(1);
  309. }
  310.